<!--
Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
Code distributed by Google as part of the polymer project is also
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
-->

<!--
`core-meta` provides a method of constructing a self-organizing database.
It is useful to collate element meta-data for things like catalogs and for 
designer.

Example, an element folder has a `metadata.html` file in it, that contains a 
`core-meta`, something like this:

    <core-meta id="my-element" label="My Element">
      <property name="color" value="blue"></property>
    </core-meta>

An application can import as many of these files as it wants, and then use 
`core-meta` again to access the collected data.

    <script>
      var meta = document.createElement('core-meta');
      console.log(meta.list); // dump a list of all meta-data elements that have been created
    </script>

Use `byId(id)` to retrive a specific core-meta.

    <script>
      var meta = document.createElement('core-meta');
      console.log(meta.byId('my-element'));
    </script>

By default all meta-data are stored in a single databse.  If your meta-data 
have different types and want them to be stored separately, use `type` to 
differentiate them.

Example:

    <core-meta id="x-foo" type="xElt"></core-meta>
    <core-meta id="x-bar" type="xElt"></core-meta>
    <core-meta id="y-bar" type="yElt"></core-meta>

    <script>
      var meta = document.createElement('core-meta');
      meta.type = 'xElt';
      console.log(meta.list);
    </script>

@group Polymer Core Elements
@element core-meta
@homepage github.io
-->

<link rel="import" href="../polymer/polymer.html">

<polymer-element name="core-meta" attributes="label type" hidden>
<script>

  (function() {
    
    var SKIP_ID = 'meta';
    var metaData = {}, metaArray = {};

    Polymer('core-meta', {
      
      /**
       * The type of meta-data.  All meta-data with the same type with be
       * stored together.
       * 
       * @attribute type
       * @type string
       * @default 'default'
       */
      type: 'default',
      
      alwaysPrepare: true,
      
      ready: function() {
        this.register(this.id);
      },
      
      get metaArray() {
        var t = this.type;
        if (!metaArray[t]) {
          metaArray[t] = [];
        }
        return metaArray[t];
      },
      
      get metaData() {
        var t = this.type;
        if (!metaData[t]) {
          metaData[t] = {};
        }
        return metaData[t];
      },
      
      register: function(id, old) {
        if (id && id !== SKIP_ID) {
          this.unregister(this, old);
          this.metaData[id] = this;
          this.metaArray.push(this);
        }
      },
      
      unregister: function(meta, id) {
        delete this.metaData[id || meta.id];
        var i = this.metaArray.indexOf(meta);
        if (i >= 0) {
          this.metaArray.splice(i, 1);
        }
      },
      
      /**
       * Returns a list of all meta-data elements with the same type.
       * 
       * @property list
       * @type array
       * @default []
       */
      get list() {
        return this.metaArray;
      },
      
      /**
       * Retrieves meta-data by ID.
       *
       * @method byId
       * @param {String} id The ID of the meta-data to be returned.
       * @returns Returns meta-data.
       */
      byId: function(id) {
        return this.metaData[id];
      }
      
    });
    
  })();
  
</script>
</polymer-element>
